package com.ebt.m.data.entity;

import com.ebt.m.data.middle.EBTFilePathHelper;
import com.ebt.m.data.middle.InsuranceObj;
import com.ebt.m.data.middle.InsuredPerson;
import com.ebt.m.data.middle.PolicyNodeMeta;
import com.ebt.m.data.middle.ProductDatainfo;
import com.ebt.m.data.middle.datatype.EAreaBenefit;
import com.ebt.m.data.middle.datatype.EController;
import com.ebt.m.data.middle.datatype.EString;
import com.ebt.m.data.middle.datatype.EUmbrellaBenefit;
import com.ebt.m.data.rxModel.apibean.ApiProduct;
import com.ebt.m.utils.ConfigData;
import com.ebt.m.utils.DataValidation;
import com.ebt.m.wiki.bean.AreaChartConfig;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 产品对象和引擎桥接的接口
 *
 * @author Michael.li
 */
public class ProductBridgeObj implements Serializable {
    /**
     * serialVersionUID
     */
    private static final long serialVersionUID = 1L;
    /**
     * 产品原型
     */
    public static final String KEY_OBJ = "ProductBridgeObj";
    /**
     * 产品类型
     */
    public static final String KEY_MODE = "ProductBridgeObj_mode";

    private ProductInfo mProduct;
    private InsuredPerson person;
    public static String QR = "";

    private HashMap<String, Object> oldData = new HashMap<>();

    public ProductInfo getmProduct() {
        return mProduct;
    }


    private InsuranceObj insuranceObj;


    private HashMap<String, Double> rateHashMap;

    public ProductBridgeObj(ProductInfo product, HashMap<String, Double> rateHashMap) {
        mProduct = product;
        this.rateHashMap = rateHashMap;
        resetInsuranceObj();
    }

    public ProductBridgeObj(ProductInfo product, InsuredPerson person, HashMap<String, Double> rateHashMap) {
        mProduct = product;
        this.rateHashMap = rateHashMap;
        this.person = person;
        resetInsuranceObj();
    }

    public ProductBridgeObj(ProductInfo product, InsuredPerson person) {
        mProduct = product;
        this.person = person;
        resetInsuranceObj();
    }

    private void resetInsuranceObj() {
        ProductDatainfo product = new ProductDatainfo();
        product.ProductId = mProduct.ProductId;
        product.CompanyId = mProduct.CompanyId;
        insuranceObj = new InsuranceObj(person, product);
        insuranceObj.setRateHashMap(rateHashMap);
        if (insuranceObj.validate()) {
            insuranceObj.init();
        }
        this.person = insuranceObj.getInsuredPerson();
    }

    /**
     * 保存旧数据
     */
    public void saveOldData() {
        oldData.clear();
        InsuredPerson oldPerson = new InsuredPerson();
        oldPerson.sex = person.sex;
        oldPerson.age = person.age;
        oldPerson.birthday = person.birthday;
        oldPerson.profession = person.profession;
        oldData.put("person", oldPerson);

        int[] oldControllerSelected = new int[insuranceObj.getAllControllers().size()];
        List<EController> list = insuranceObj.getAllControllers();
        for (int i = 0; i < list.size(); i++) {
            EController eController = list.get(i);
            oldControllerSelected[i] = eController.getSelectedIndex();
        }
        oldData.put("oldControllerSelected", oldControllerSelected);

        oldData.put("coverage", insuranceObj.getCoverage());
        oldData.put("premium", insuranceObj.getPremium());
    }

    public InsuredPerson getPerson() {
        if (this.person == null) {
            this.person = insuranceObj.getInsuredPerson();
        }
        return this.person;
    }

    public synchronized void setPerson(InsuredPerson person) {
        if (person != null) {
            this.person.sex = person.sex;
            this.person.age = person.age;
            this.person.profession = person.profession;
            insuranceObj.resetData(person);
        }
    }

    public InsuranceObj getInsuranceObj() {
        return insuranceObj;
    }

    public int getProductId() {
        return mProduct.ProductId;
    }

    public String getProductName() {
        return mProduct.Name;
    }

    /**
     * 彩页 全路径
     *
     * @return
     */
    public String[] getColorPagesPath() {
        return insuranceObj.getPictureURL();
    }

    /**
     * 顺序为条款目录、条款、名词解释、CSS样式表的全路径
     *
     * @return
     */
    public String[] getClauseRelatedPath() {
        String[] array = new String[4];
        array[0] = insuranceObj.getListURL();
        array[1] = insuranceObj.getTermURL();
        //FIXME-DAMON-20160627
//        array[2] = EBTFilePathHelper.getCompanyInterpretationName(String.valueOf(mProduct.CompanyId));
        array[2] = EBTFilePathHelper.getCompanyInterpretationName(String.valueOf(mProduct.CompanyId), String.valueOf(mProduct.Id));
        array[3] = ConfigData.PATH_RESOURCES + "theme.css";
        return array;
    }

    /**
     * 返回面积图对应的项目
     *
     * @return
     */
    private List<EAreaBenefit> getAreaItems() {
        List<EAreaBenefit> list = new ArrayList<EAreaBenefit>();

        for (PolicyNodeMeta meta : insuranceObj.getAreaBenefitList()) {
            EAreaBenefit obj = (EAreaBenefit) meta.getEBTValue();
            Object[] values = insuranceObj.getBenefitData(meta.getFieldName());
            obj.setDictation(insuranceObj.getDictation(meta.getFieldName()));
            obj.setTermText(insuranceObj.getTermText(meta.getFieldName()));
            obj.setValues(values);
            obj.setFieldName(meta.getFieldName());
            list.add(obj);
        }
        return list;
    }

    /**
     * 返回伞图对应的项目 FIXME 返回类型需要重新定义
     *
     * @return
     */
    public List<EUmbrellaBenefit> getUmbrellaItems() {
        List<EUmbrellaBenefit> list = new ArrayList<EUmbrellaBenefit>();

        for (PolicyNodeMeta meta : insuranceObj.getUmbrellaBenefitList()) {
            EUmbrellaBenefit obj = (EUmbrellaBenefit) meta.getEBTValue();
            obj.setDictation(insuranceObj.getDictation(meta.getFieldName()));
            obj.setTermText(insuranceObj.getTermText(meta.getFieldName()));
            obj.setFieldName(meta.getFieldName());
            try {
                obj.setName(insuranceObj.operateBenifitDesc(obj.getName()));
            } catch (Exception e) {
                e.printStackTrace();
            }
            list.add(obj);
        }
        return list;
    }

    public String getJsonObj() {
        return getJsonObj(insuranceObj);
    }

    public static String getJsonObj(InsuranceObj obj) {
        return getJsonArray(obj).toString();
    }

    public static JSONArray getJsonArray(InsuranceObj obj) {
        JSONArray array = new JSONArray();
        List<PolicyNodeMeta> list = obj.getControllerNode();
        PolicyNodeMeta node = obj.getCoverageUseAnotherFieldname();
        String fieldName = "";
        if (node != null) {
            EString es = (EString) node.getEBTValue();
            fieldName = es.getValue();
        }
        for (PolicyNodeMeta meta : list) {
            try {
                EController eController = (EController) meta.getEBTValue();
                if (!fieldName.equals(meta.getFieldName())) {
                    JSONObject js = new JSONObject();
                    js.put("DisplayName", eController.getDisplayName());
                    js.put("FieldName", meta.getFieldName());
                    js.put("Value", eController.getSelectedValue());
                    js.put("ItemName", eController.getSelectedName());
                    js.put("Index", eController.getSelectedIndex());
                    js.put("isCoverageUseAnother", "false");
                    array.put(js);
                } else {
                    JSONObject js = new JSONObject();
                    js.put("DisplayName", eController.getDisplayName());
                    js.put("FieldName", meta.getFieldName());
                    js.put("Value", eController.getSelectedValue());
                    js.put("ItemName", eController.getSelectedName());
                    js.put("Index", eController.getSelectedIndex());
                    js.put("isCoverageUseAnother", "true");
                    array.put(js);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return array;
    }

    /**
     * 获取投保选项包括保额保费
     *
     * @return
     */
    public JSONArray getJsonObjWithCoverageAndPremium() {
        JSONArray array = new JSONArray();
        List<PolicyNodeMeta> list = insuranceObj.getControllerNode();
        PolicyNodeMeta node = insuranceObj.getCoverageUseAnotherFieldname();
        // 若保额单位不是元，则需要用到保额取代字段显示单位,默认为空
        String itemNameOfCoverageUseAnother = "";
        String fieldName = "";
        if (node != null) {
            EString es = (EString) node.getEBTValue();
            fieldName = es.getValue();
        }
        for (PolicyNodeMeta meta : list) {
            try {
                EController eController = (EController) meta.getEBTValue();
                if (!fieldName.equals(meta.getFieldName())) {
                    JSONObject js = new JSONObject();
                    js.put("DisplayName", eController.getDisplayName());
                    js.put("FieldName", meta.getFieldName());
                    js.put("Value", eController.getSelectedValue());
                    js.put("ItemName", eController.getSelectedName());
                    js.put("Index", eController.getSelectedIndex());
                    js.put("isCoverageUseAnother", "false");
                    array.put(js);
                } else {
                    JSONObject js = new JSONObject();
                    js.put("DisplayName", eController.getDisplayName());
                    js.put("FieldName", meta.getFieldName());
                    js.put("Value", eController.getSelectedValue());
                    js.put("ItemName", eController.getSelectedName());
                    js.put("Index", eController.getSelectedIndex());
                    js.put("isCoverageUseAnother", "true");
                    itemNameOfCoverageUseAnother = eController.getSelectedName();
                    array.put(js);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        try {
            //追加保额保费
            JSONObject coverage = new JSONObject();
            coverage.put("DisplayName", "保额");
            coverage.put("FieldName", "Coverage");
            coverage.put("Value", getCoverage() + "");
            coverage.put("ItemName", itemNameOfCoverageUseAnother);
            array.put(coverage);

            JSONObject premium = new JSONObject();
            premium.put("DisplayName", "保费");
            premium.put("FieldName", "Premium");
            premium.put("Value", getPremium() + "");
            premium.put("ItemName", "");
            array.put(premium);
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return array;
    }

    public double getCoverage() {
        return insuranceObj.getCoverage();
    }

    public double getPremium() {
        return insuranceObj.getPremium();
    }

    public boolean hasAreaChart() {
        return insuranceObj.getAreaBenefitList().size() > 0;
    }

    public boolean hasUmbrellaChartChart() {
        return insuranceObj.getUmbrellaBenefitList().size() > 0;
    }

    /**
     * 获取已经排序过的面积图数据列表
     *
     * @return
     */
    public List<AreaChartConfig> getAreaChartConfigList() {
        List<AreaChartConfig> list = new ArrayList<AreaChartConfig>();
        List<EAreaBenefit> items = getAreaItems();
        AreaChartConfig config;
        int[] xArray = null;
        for (EAreaBenefit item : items) {
            Object[] xy = item.getValues();
            xArray = new int[item.getValues().length];
            for (int i = 0; i < xArray.length; i++) {
                xArray[i] = (int) (((double[]) xy[i])[0]);
            }
            String recordFile = null;
            //20160617屏蔽声音文件解析
//            List<String> voicePackage = item.getVoicePackage();
//            if (voicePackage != null && voicePackage.size() > 0) {
//                recordFile = EBTFilePathHelper.getProductVoiceName(String.valueOf(mProduct.CompanyId), String.valueOf(mProduct.ProductId), voicePackage.get(0));
//            }
            config = new AreaChartConfig(item.getName(), item.getImgStyle(), 5, item.getColor(), 5, item.getColor(), item.getDictation(), item.getTermText(), item.getAnchor(),
                    item.getImgLevelWeight(), item.getSortNo(), recordFile, xArray, item.getValues());
            config.setFieldName(item.getFieldName());
            //设置最长终期年龄
            config.setMaxInsuredAge(item.getMaxInsuredAge());
            list.add(config);
            // System.out.println(recordFile);
        }
        return list;
    }

    public String getFavoriteJson() {
        JSONObject jsonObj = new JSONObject();
        try {
            JSONObject personObj = new JSONObject();
            personObj.put("age", person.age);
            personObj.put("profession", person.profession);
            personObj.put("sex", person.sex);
            personObj.put("isCoverageUnitFenshu", insuranceObj.isFenshu());
            personObj.put("coverage", getCoverage());
            personObj.put("premium", getPremium());
            jsonObj.put("person", personObj);
            jsonObj.put("items", getJsonArray(insuranceObj));
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return jsonObj.toString();
    }

    public void setFavorite(String json) {
        try {
            JSONObject jsonObj = new JSONObject(json);
            JSONObject personObj = jsonObj.optJSONObject("person");
            JSONArray array = jsonObj.optJSONArray("items");
            if (personObj == null || array == null) {
                return;
            }
            if (person.age != personObj.optInt("age")) {
                return;
            }
            if (!person.sex.equalsIgnoreCase(personObj.optString("sex"))) {
                return;
            }
            if (person.profession != personObj.optInt("profession")) {
                return;
            }
            insuranceObj.setCoverage(personObj.optDouble("coverage"));
            insuranceObj.setPremium(personObj.optDouble("premium"));
            for (int i = 0; i < array.length(); i++) {
                JSONObject item = array.getJSONObject(i);
                String fieldName = item.optString("FieldName");
                double value = item.optDouble("Value");
                insuranceObj.setControllerSelectedIndexByFieldName(fieldName, getIndexBy(insuranceObj, fieldName, value));
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private int getIndexBy(InsuranceObj obj, String fieldName, double value) {
        int ret = -1;
        List<PolicyNodeMeta> list = obj.getControllerNode();
        EController c = null;
        for (PolicyNodeMeta meta : list) {
            c = (EController) meta.getEBTValue();
            if (meta.getFieldName().equalsIgnoreCase(fieldName)) {
                ret = getIndexBy(value, c.getItems());
                break;
            }
        }
        return ret;
    }

    private int getIndexBy(double value, double[] items) {
        int ret = -1;
        for (int i = 0; i < items.length; i++) {
            if (items[i] == value) {
                ret = i;
                break;
            }
        }
        return ret;
    }

    /**
     * 解析modelmap
     *
     * @param modelInfoStr
     * @param modelPre
     * @return
     * @throws Exception
     */
    public static HashMap<String, String> parseModelToNodeMaps(String modelInfoStr, String modelPre) throws Exception {
        HashMap<String, String> tModelMaps = new HashMap<String, String>();
        if (!DataValidation.isEmpty(modelInfoStr)) {
            JSONObject obj = new JSONObject(modelInfoStr);
            JSONArray modelNames = obj.getJSONArray("key");
            JSONArray nodeNames = obj.getJSONArray("value");
            if (DataValidation.isEmpty(modelPre)) {
                for (int i = 0; i < modelNames.length(); i++) {
                    String modelName = modelNames.getString(i);
                    String nodeName = nodeNames.getString(i);
                    tModelMaps.put(modelName, nodeName);
                }
            } else {
                for (int i = 0; i < modelNames.length(); i++) {
                    String nodeName = nodeNames.getString(i);
                    String modelName = modelNames.getString(i);
                    if (modelName.contains(modelPre)) {
                        tModelMaps.put(modelName, nodeName);
                    }
                }
            }

        } else {
            throw new Exception("model初始化错误");
        }
        return tModelMaps;
    }

    /**
     * 解析modelmap
     *
     * @param modelMapBean
     * @param modelPre
     * @return
     * @throws Exception
     */
    public static HashMap<String, String> parseModelToNodeMaps(ApiProduct.ModelMapBean modelMapBean, String modelPre) throws Exception {
        HashMap<String, String> tModelMaps = new HashMap<String, String>();
        if (modelMapBean != null) {
            if (DataValidation.isEmpty(modelPre)) {
                for (int i = 0; i < modelMapBean.getKey().size(); i++) {
                    String nodeName = modelMapBean.getValue().get(i);
                    String modelName = modelMapBean.getKey().get(i);
                    tModelMaps.put(modelName, nodeName);
                }
            } else {
                for (int i = 0; i < modelMapBean.getKey().size(); i++) {
                    String nodeName = modelMapBean.getValue().get(i);
                    String modelName = modelMapBean.getKey().get(i);
                    if (modelName.contains(modelPre)) {
                        tModelMaps.put(modelName, nodeName);
                    }
                }
            }

        } else {
            throw new Exception("model初始化错误");
        }
        return tModelMaps;
    }

    /**
     * 获取面积利益节点
     *
     * @return
     */
    public List<PolicyNodeMeta> getAreaBenefitList() {
        return insuranceObj.getAreaBenefitList();
    }

    /**
     * 获取伞图利益节点
     *
     * @return
     */
    public List<PolicyNodeMeta> getUmbrellaBenefitList() {
        return insuranceObj.getUmbrellaBenefitList();
    }

    public void setPersonAndControllers(String json) {
        try {
            JSONObject jsonObj = new JSONObject(json);
            JSONObject personObj = jsonObj.optJSONObject("person");
            JSONArray array = jsonObj.optJSONArray("items");
            if (personObj != null) {
                boolean isPersonChange = false;
                if (person.age != personObj.optInt("age")) {
                    person.age = personObj.optInt("age");
                    isPersonChange = true;
                }
                if (!person.sex.equalsIgnoreCase(personObj.optString("sex"))) {
                    person.sex = personObj.optString("sex");
                    isPersonChange = true;
                }
                if (person.profession != personObj.optInt("profession")) {
                    person.profession = personObj.optInt("profession");
                    isPersonChange = true;
                }
                if (isPersonChange) {
                    insuranceObj.resetData(person);
                }
                insuranceObj.setCoverage(personObj.optDouble("coverage"));
                insuranceObj.setPremium(personObj.optDouble("premium"));
            }
            if (array != null) {
                for (int i = 0; i < array.length(); i++) {
                    JSONObject item = array.getJSONObject(i);
                    String fieldName = item.optString("FieldName");
                    double value = item.optDouble("Value");
                    insuranceObj.setControllerSelectedIndexByFieldName(fieldName, getIndexBy(insuranceObj, fieldName, value));
                }
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    /**
     * 点击取消的时候恢复数据
     */
    public void resetData() {
        try {
            if (oldData != null) {
                InsuredPerson oldPerson = (InsuredPerson) oldData.get("person");
                if (oldPerson != null) {
                    person.age = oldPerson.age;
                    person.sex = oldPerson.sex;
                    person.profession = oldPerson.profession;
                    person.birthday = oldPerson.birthday;
                }
                int[] oldControllerSelected = (int[]) oldData.get("oldControllerSelected");
                if (oldControllerSelected != null) {
                    for (int i = 0; i < insuranceObj.getAllControllers().size(); i++) {
                        EController eController = insuranceObj.getAllControllers().get(i);
                        eController.setSelectedIndex(oldControllerSelected[i]);
                    }
                }
                insuranceObj.setCoverage((Double) oldData.get("coverage"));
                insuranceObj.setPremium((Double) oldData.get("premium"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}
